import { useEffect, useState } from 'react';
import axios from 'axios';
import BpmnModeler from 'bpmn-js/lib/Modeler';
import 'bpmn-js/dist/assets/diagram-js.css'; // 左边工具栏以及编辑节点的样式
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';

import propertiesPanelModule from 'bpmn-js-properties-panel';
import bpmnPropertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/bpmn';
// use Camunda BPMN namespace
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda';
import camundaModdleDescriptors from 'camunda-bpmn-moddle/resources/camunda';
// import propertiesProviderModule from './components/properties-panel-extension/provider/camunda';
// import camundaModdleDescriptors from './components/properties-panel-extension/descriptors/camunda';

// 自定义属性栏
import reviewerPropertiesProviderModule from './components/properties-panel-extension/provider/reviewer';
import reviewerModdleDescriptors from './components/properties-panel-extension/descriptors/reviewer';

import 'bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css'; // 右边工具栏样式
import './index.scss';
import { notification } from 'antd';
import startXml from './sources/start';
import BpmnToolBar from '@/components/Bpmn/components/BpmnToolBar';
import customTranslateModule from './customTranslate';
import { fetchFlowDiagram } from '@/api/workFlow/mgt';

const ReactBpmn = (props) => {
  const { id, onSave, xml, activeList, readOnly = true } = props;

  const [bpmnModelerObj, setBpmnModelerObj] = useState('');
  const [bpmnInfo, setBpmnInfo] = useState({ name: '', processKey: '', content: '' });
  const [xmlStr, setXmlStr] = useState('');

  const bpmnBaseConfig = {
    container: '#canvas', // 添加控制板
    height: '100%',
    width: '100%'
  };

  const bpmnDesignConfig = {
    ...bpmnBaseConfig,
    propertiesPanel: {
      parent: '#js-properties-panel'
    },

    additionalModules: [
      // 右边的属性栏
      propertiesPanelModule,
      bpmnPropertiesProviderModule,
      propertiesProviderModule,
      // reviewerPropertiesProviderModule,
      customTranslateModule
    ],
    moddleExtensions: {
      camunda: camundaModdleDescriptors
      // reviewer: reviewerModdleDescriptors
    }
  };

  // 模拟请求后台获取bpmn文件地址
  const getXmlUrl = (id) => {
    return new Promise((resolve) => {
      fetchFlowDiagram(id).then((res) => {
        const { data } = res;
        setBpmnInfo(data);
        resolve(res.data?.content || '');
      });
    });
  };

  // 下载为bpmn格式,done是个函数，调用的时候传入的
  const getDiagram = (done) => {
    // 把传入的done再传给bpmn原型的saveXML函数调用
    bpmnModelerObj.saveXML({ format: true }, (err, xml) => {
      done(err, xml);
    });
  };

  // 下载为bpmn格式,done是个函数，调用的时候传入的
  const saveDiagram = () => {
    getDiagram((_err, xml) => {
      onSave(xml);
    });
  };

  // 添加绑定事件
  const addBpmnListener = () => {
    // 给图绑定事件，当图有发生改变就会触发这个事件
    bpmnModelerObj.on('commandStack.changed', () => {
      getDiagram((_err, xml) => {
        console.log(xml); // 这里获取到的就是最新的xml信息
      });
    });
  };

  const success = () => {
    console.log('创建成功!');
    addBpmnListener();
  };

  const transformCanvas = (bpmnXmlStr) => {
    // 将字符串转换成图显示出来
    bpmnModelerObj.importXML(bpmnXmlStr, (err) => {
      if (err) {
        console.error(err);
        notification.error({
          message: '提示',
          description: '导入失败'
        });
      } else {
        success();
      }
      // 让图能自适应屏幕
      const canvas = bpmnModelerObj.get('canvas');
      canvas.zoom('fit-viewport', 'auto');
      if (activeList?.length > 0) {
        const modeling = bpmnModelerObj.get('modeling');
        const elements = activeList.map((id) => bpmnModelerObj.get('elementRegistry').get(id));
        modeling.setColor(elements, {
          stroke: '#1E88E5'
        });
      }
    });
  };

  const createNewDiagram = async () => {
    // 将字符串转换成图显示出来
    if (xmlStr === '') {
      // 若是后台没有数据则使用默认的一个xml
      const bpmnXmlStr = startXml
        .replace(/PROCESS_KEY/g, bpmnInfo.processKey)
        .replace('PROCESS_NAME', bpmnInfo.name);

      transformCanvas(bpmnXmlStr);
    } else {
      transformCanvas(xmlStr);
    }
  };

  useEffect(() => {
    if (bpmnModelerObj) {
      createNewDiagram();
    }
  }, [bpmnModelerObj]);

  const initBpmn = () => {
    setBpmnModelerObj(new BpmnModeler(readOnly ? bpmnBaseConfig : bpmnDesignConfig));
  };

  const init = async () => {
    if (xml) {
      setXmlStr(xml);
    } else if (id) {
      setXmlStr(await getXmlUrl(id));
    }
    initBpmn();
  };

  useEffect(() => {
    console.log('effect', readOnly);
    init();
  }, []);

  const click = () => {
    const line = bpmnModelerObj.get('Flow_18nk6x1');
    console.log('click line', line);
  };

  return (
    <>
      <div className="bpmn-container">
        <BpmnToolBar
          bpmnModeler={bpmnModelerObj}
          onSave={() => {
            saveDiagram();
          }}
        />
        <div id="canvas" className="canvas"></div>
        <div id="js-properties-panel" className="panel"></div>
      </div>
    </>
  );
};

export default ReactBpmn;
